
const TypeDef = require('./typedef');
const cv = require('opencv4nodejs');
const jmp = require('jimp');
const uuidV1 = require('uuid');
const m = require('./logger');

module.exports = {cvImages,cvImagesBase64,parseImage,drawFace};


// opencv 处理图像
function cvImages(imgFile,isIR,filePath) {
    let img = cv.imread(imgFile);
    let height  = img.rows;
    let width = img.cols - img.cols % 4;
    let widthStep = width * img.channels;
    let type = img.type;

    // 此方法图片错乱
    // let imgData = img.getData();
    // new cv.Mat(imgData,height,width,type);
    // 此方法只压缩图片
    // let newImg = img.resize(new cv.Size(width,height));
    // getRegion 的 Mat 不能 使用getData, 用copyTo的方法拷贝到新Mat中
    let region = img.getRegion(new cv.Rect(0,0,width,height));
    let newImg = new cv.Mat(height,width,type);
    region.copyTo(newImg);

    // 写文件测试
    let name = filePath + '/' + uuidv.v1().toString().replace('-','') + '_test.jpg';
    cv.imwrite(name ,newImg);
    let asvl = new TypeDef.ASVLOFFSCREEN();
    let imgBuffer;

    if(isIR){
        console.log("IR图像处理....");
        // opencv读图时会将灰度图读成RGB图，需要转换成GRAY图进行IR活体检测
        imgBuffer = newImg.cvtColor(cv.COLOR_RGBA2GRAY).getData();
        asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_GRAY;
    }else {
        console.log("RGB图像处理....");
        imgBuffer = newImg.getData();
        asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_RGB24_B8G8R8;
    }

    asvl.i32Width = width;
    asvl.i32Height = height;
    asvl.ppu8Plane[0] = imgBuffer;
    asvl.pi32Pitch[0] = widthStep;
    asvl.gc_ppu8Plane0 = imgBuffer;

    // 释放读取资源
    img.release();
    newImg.release();
    region.release();

    return {
        width: width,
        height: height,
        imageBuffer: imgBuffer,
        imageData: asvl,
    };
}

// opencv 处理图像
function cvImagesBase64(img64,isIR,filePath) {
    try{

        let buf = new Buffer(img64, 'base64');
        console.log("buf",buf.length);
        let img = cv.imdecode(buf,cv.IMREAD_COLOR);
        let height  = img.rows;
        let width = img.cols - img.cols % 4;
        let widthStep = width * img.channels;
        let type = img.type;

        // 此方法图片错乱
        // let imgData = img.getData();
        // new cv.Mat(imgData,height,width,type);
        // 此方法只压缩图片
        // let newImg = img.resize(new cv.Size(width,height));
        // getRegion 的 Mat 不能 使用getData, 用copyTo的方法拷贝到新Mat中
        let region = img.getRegion(new cv.Rect(0,0,width,height));
        let newImg = new cv.Mat(height,width,type);
        region.copyTo(newImg);

        // 写文件测试
        let name = filePath + '/' + uuidV1.v1().toString().replace('-','') + '_test.jpg';
        cv.imwrite(name ,newImg);
        let asvl = new TypeDef.ASVLOFFSCREEN();
        let imgBuffer;

        if(isIR){
            console.log("IR图像处理....");
            // opencv读图时会将灰度图读成RGB图，需要转换成GRAY图进行IR活体检测
            imgBuffer = newImg.cvtColor(cv.COLOR_RGBA2GRAY).getData();
            asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_GRAY;
        }else {
            console.log("RGB图像处理....");
            imgBuffer = newImg.getData();
            asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_RGB24_B8G8R8;
        }

        asvl.i32Width = width;
        asvl.i32Height = height;
        asvl.ppu8Plane[0] = imgBuffer;
        asvl.pi32Pitch[0] = widthStep;
        asvl.gc_ppu8Plane0 = imgBuffer;

        // 释放读取资源
        img.release();
        newImg.release();
        region.release();

        return {
            width: width,
            height: height,
            imageBuffer: imgBuffer,
            imageData: asvl,
        };
    }catch (e) {
        m.logger.error("face_cv_image.js-cvImagesBase64 error:%o",e);
        return null;
    }

}


// jimp 处理图像
function parseImage(imgFile,isIR) {
    return jmp
        .read(imgFile)
        .then(image => {
            let {width, height, data} = image.bitmap;
            width = width - width % 4;
            let imageBuf = new Buffer(width * height * 3);
            let asvl = new TypeDef.ASVLOFFSCREEN();

            if(isIR){
                image.grayscale()
            }

            image.
            image.scan(0, 0, width, height, function (i, j, idx) {
                let r = data[idx];
                let g = data[idx + 1];
                let b = data[idx + 2];

                imageBuf[(j * width + i) * 3] = b;
                imageBuf[(j * width + i) * 3 + 1] = g;
                imageBuf[(j * width + i) * 3 + 2] = r;
            });

            if(isIR){
                asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_GRAY
            }else{
                asvl.u32PixelArrayFormat = TypeDef.ASVL_PAF_RGB24_B8G8R8;
            }
            asvl.i32Width = width;
            asvl.i32Height = height;
            asvl.ppu8Plane[0] = imageBuf;
            asvl.pi32Pitch[0] = asvl.i32Width * 3;
            asvl.gc_ppu8Plane0 = imageBuf;

            return {
                width: width,
                height: height,
                imageBuffer: imageBuf,
                imageData: asvl,
            };
        });
}

// 标记人脸并预览
function drawFace(imgFile,infos,isPreView,filePath) {
    let frame = cv.imread(imgFile);
    for (let i = 0; i < infos.faceNum; i++) {
        let rect = infos.faceRect[i];

        console.log('rect',rect)

        let x = rect.left;
        let y = rect.top;
        let rows = rect.bottom - rect.top;
        let cols = rect.right - rect.left;

        // resize只是缩放
        // let crop = frame.resize(new cv.Size(cols,rows),x,y);
        // getRegion 根绝坐标截图
        let crop = frame.getRegion(new cv.Rect(x,y,cols,rows));

        let name = uuidv.v1().toString().replace('-','') + '_' + i;
        cv.imwrite(filePath + '/' + name +'.jpg', crop);
        // 画人脸框
        frame.drawRectangle(
            new cv.Rect(x,y,cols,rows),
            new cv.Vec3(0, 0, 255),
            2,
            cv.LINE_8,
            0
        );

        if (isPreView){
            cv.imshow(name,crop);
        }
    }
    let frameName = uuidv.v1().toString().replace('-','') + '_frame';
    cv.imwrite(filePath + '/' + frameName +'.jpg', frame);
    if (isPreView) {
        cv.imshow(frameName, frame);
        cv.waitKey(0);
        cv.destroyWindow(frameName);
    }
    return frame;
}
